/**
 * \file sm4.h
 */
#ifndef XYSSL_SM4_H
#define XYSSL_SM4_H

#define SM4_ENCRYPT     1
#define SM4_DECRYPT     0

/**
 * \brief          SM4 context structure
 */
typedef struct
{
    int mode;                   /*!<  encrypt/decrypt   */
    unsigned long sk[32];       /*!<  SM4 subkeys       */
}
sm4_context;


#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief   SM4算法加密运算初始化
 *
 * @param   ctx         待初始化的SM4加密运算上下文信息
 * @param   key[16]     16字节密钥数据
 */
void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] );

/**
 * @brief   SM4算法解密运算初始化
 *
 * @param   ctx         待初始化的SM4解密运算上下文信息
 * @param   key[16]     16字节密钥数据
 */
void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] );

/**
 * @brief   SM4算法ECB模式数据加解密运算
 *
 * @param   ctx         SM4运算上下文信息
 * @param   length      输入数据长度（16字节整倍数）
 * @param   input       输入数据的缓冲区指针
 * @param   output      输出数据的缓冲区指针
 *
 * @return  实际输出数据长度
 */
int sm4_crypt_ecb( sm4_context *ctx,
        int length,
        unsigned char *input,
        unsigned char *output);

/**
 * @brief   SM4算法CBC模式数据加解密运算
 *
 * @param   ctx         SM4算法上下文信息
 * @param   iv[16]      初始向量，函数内对其进行更新
 * @param   length      输入数据长度（16字节整倍数）
 * @param   input       输入数据的缓冲区指针
 * @param   output      输出数据的缓冲区指针
 *
 * @return  实际输出数据长度
 */
int sm4_crypt_cbc( sm4_context *ctx,
        unsigned char iv[16],
        int length,
        unsigned char *input,
        unsigned char *output );

/**
 * @brief   SM4算法CFB模式数据加解密运算
 *
 * @param   ctx         SM4算法上下文信息
 * @param   iv[16]      初始向量，函数内对其进行更新，数据长度不为16整倍数时更新的IV不可连续使用
 * @param   length      输入数据长度
 * @param   input       输入数据的缓冲区指针
 * @param   output      输出数据的缓冲区指针
 *
 * @return  实际输出数据长度
 */
int sm4_crypt_cfb( sm4_context *ctx,
        unsigned char iv[16],
        int length,
        unsigned char * input,
        unsigned char * output);

/**
 * @brief   SM4算法OFB模式数据加解密运算
 *
 * @param   ctx         SM4算法上下文信息
 * @param   iv[16]      初始向量，函数内对其进行更新
 * @param   length      输入数据长度
 * @param   input       输入数据的缓冲区指针
 * @param   output      输出数据的缓冲区指针
 *
 * @return  实际输出数据长度
 */
int sm4_crypt_ofb( sm4_context *ctx,
        unsigned char iv[16],
        int length,
        unsigned char * input,
        unsigned char * output);

#ifdef __cplusplus
}
#endif

#endif /* sm4.h */

